import React from "react";

import { NavBar, Icon, Toast } from 'antd-mobile'

// 导入Api
import api from '../../api/api'

import { List, AutoSizer } from 'react-virtualized';

// import './index.scss'

// 导入CSSModules 的样式文件
import styles from './index.module.css'

// 导入utils中获取城市定位的方法
import { getCurrentCity } from '../../utils/index'

// 导入NavHeader组件
import NavHeader from '../../components/NavHeader'
console.log(styles)
function functionfunc1() {
  var nAdd = ()=> {
    this.n += 1;
    console.log(this.n)
  }
 let functionfunc2=()=>{ console.log(n) } 
 return func2
} 
var result = func1()
 result() 
 nAdd() 
 result()
// 数据格式化的方法
const formatCityData = (list) => {
  const cityList = {}

  //  1.遍历list数组
  list.forEach(item => {
    // 2.获取每一个城市的首字母
    let first = item.short.substring(0, 1)
    // 3.判断 cityList 中是否有该分类
    if (cityList[first]) {
      // 4.如果有，直接往该分类中push数据
      cityList[first].push(item)
    } else {
      // 5.如果没有，就先创建一个数组，然后，把当前城市信息添加到数组中
      cityList[first] = [item]
    }
  })
  // 获取索引数据（对象的每一个键）
  // Object.keys()遍历  (返回一个数组=>元素是对象的键) sort() 方法以字母顺序对数组进行排序：
  const cityIndex = Object.keys(cityList).sort()
  return {
    cityList,
    cityIndex
  }
}

// 索引(A,B等)的高度
const TITLE_HEIGHT = 36
// 每个城市名称的高度
const NAME_HEIGHT = 50

// 封装处理字母索引的方法
const formatCityIndex = (item) => {
  switch (item) {
    case '#':
      return '当前定位'
    case 'hot':
      return '热门城市'
    default:
      return item.toUpperCase()
  }
}
// 有房源的城市
const HOUSE_CITY = ['北京', '上海', '深圳', '广州']

export default class CityList extends React.Component {
  constructor(props) {
    // 需要在constructor中访问this.props时，才需要设置super(props)
    super(props) // 如果不调用super方法，子类就得不到this对象

    this.state = {
      cityList: {},
      cityIndex: [],
      active_index: 0
    }

    // 创建ref对象
    this.cityListComponent = React.createRef()
  }


  async componentDidMount() {
    await this.getCityList()

    // 调用List 组件提供的 measureAllRows 方法，提前计算 List 组件中每一行的高度，
    // 实现scrollToRow 方法的精确跳转 
    // 注意：调用这个方法的时候，需要保证 List 组件中已经有数据了！如果 List 组件中
    // 数据为空，就会导致调用方法报错！
    // 解决:只要保证这个方法是在获取到数据之后调用即可. 使用 async await
    this.cityListComponent.current.measureAllRows()
  }

  // 获取城市列表、热门城市数据   
  async getCityList() {
    const params = { level: 1 }
    const res = await api.get('/area/city', params)
    let { cityList, cityIndex } = formatCityData(res.data.body)
    // 获取热门城市数据

    const { data } = await api.get('/area/hot')
    //  把热门城市数据添加到 CityList 中
    cityList['hot'] = data.body
    //  把热门城市数据的索引添加到 cityIndex 中
    cityIndex.unshift('hot')

    // 获取当前定位城市
    const curCity = await getCurrentCity()

    cityList['#'] = [curCity]
    cityIndex.unshift('#')
    this.setState({
      cityList,
      cityIndex
    })
  }

  // 切换城市
  async changeCity({ label, value }) {
    console.log(label, value);
    // indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。 
    // 注释：如果要检索的字符串值没有出现，则该方法返回 -1
    if (HOUSE_CITY.indexOf(label) > -1) {
      // 有房源数据   把当前城市信息保存到本地  
      localStorage.setItem('hkzf_city', JSON.stringify({ label, value }))
      this.props.history.go(-1)
    } else {
      Toast.info('此城市暂无房源数据', 1, null, false);
    }
  }

  // 渲染每一行数据的渲染函数，函数的返回值就是最终在页面渲染的内容
  rowRenderer = ({
    key, // 键
    index, // 索引
    isScrolling, // 当前项是否正在滚动
    isVisible, // 当前项在 List 中是可见的
    style, // 注意:重点属性，一定要给每一行添加该样! 作用:指定每一行的位置
  }) => {
    const { cityIndex, cityList } = this.state
    // 获取每一行的字母索引
    let letter = cityIndex[index]

    return (
      // 每一个字母分类下的数据都划分为一行
      <div key={key} style={style} className={styles.city}>
        {/* 字母索引 */}
        <div className={styles.title}>{formatCityIndex(letter)}</div>
        {/* 字母索引--城市名称 */}
        {cityList[letter].map(item =>
          <div className={styles.name} key={item.value} onClick={() => this.changeCity(item)}>{item.label}</div>
        )}

      </div>
    );
  }

  // 创建动态计算每一行高度的方法
  getRowHeight = ({ index }) => {
    const { cityIndex, cityList } = this.state
    // 获取每一行的字母索引
    let letter = cityIndex[index]
    // 索引标题高度 + (城市数量 * 城市名称的高度)
    return TITLE_HEIGHT + (cityList[letter].length * NAME_HEIGHT)
  }

  // 渲染右侧索引列表的方法 
  renderCityIndex = () => {
    const { active_index, cityIndex } = this.state
    return cityIndex.map((item, index) =>
      <li
        key={item}
        className={styles.cityIndexItem}
        onClick={() => {
          // this.cityListComponent.current 获取li组件的ref对象   
          // scrollToRow()是<List>组件自带的方法  用于接收一个索引跳转到指定索引的位置
          this.cityListComponent.current.scrollToRow(index)

        }
        }>
        <span className={active_index === index ? styles.indexActive : ''} onClick={() => this.setState({
          active_index: index
        })}>
          {item === 'hot' ? '热' : item.toUpperCase()}
        </span>
      </li>
    )
  }

  // 用于获取 List 组件的行信息  startIndex 当前行的起始索引 每一个字母+下面的城市为一行
  onRowsRendered = ({ startIndex }) => {
    if (this.state.active_index !== startIndex) {
      this.setState({
        active_index: startIndex
      })
    }
  }

  render() {
    return <div className={styles.citylist} >
      {/* 顶部导航栏 */}
      <NavHeader>
        城市选择
      </NavHeader>

      {/* 城市列表  List 列表组件  AutoSizer用来设置 List组件的宽/高 父盒子的100%,
      所以要处理一下 顶部导航栏 跟着滚动的问题*/}
      <AutoSizer>
        {
          ({ height, width }) => (
            <List
              ref={this.cityListComponent}  // 关联创建好的ref对象
              width={width} // List 组件的高度
              height={height} // List 组件的宽度
              rowCount={this.state.cityIndex.length}// 告诉组件数据有多少行
              rowHeight={this.getRowHeight} // 每一行的高度
              rowRenderer={this.rowRenderer} //  渲染每一行数据的函数
              onRowsRendered={this.onRowsRendered} // 获取行信息的函数
              scrollToAlignment="start" // 设置点击滚动的对齐方式 start 顶部对齐  end 底部
            />
          )
        }
      </AutoSizer>

      {/* 右侧索引列表 */}
      <ul className={styles.cityIndex}>{this.renderCityIndex()}</ul>


    </div>
  }
}